package com.binhthuan.catechist.client.data;

import com.binhthuan.catechist.client.ECApplication;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.OperationBinding;
import com.smartgwt.client.data.RestDataSource;
import com.smartgwt.client.types.CriteriaPolicy;
import com.smartgwt.client.types.DSDataFormat;
import com.smartgwt.client.types.DSOperationType;
import com.smartgwt.client.types.DSProtocol;
import com.smartgwt.client.util.JSOHelper;
import com.smartgwt.client.util.JSON;

public abstract class AbstractDS extends RestDataSource {
    public static class Response extends JavaScriptObject {
        protected Response() {
        }

        public final native int getStatus() /*-{
            return this.response.status;
        }-*/;

        public final native boolean isSuccess() /*-{
            return this.response.status == 0;
        }-*/;

        public final native boolean getRequireConfirmation() /*-{
            return this.response._requireConfirmation == true;
        }-*/;

        public final native JavaScriptObject getErrors() /*-{
            return this.response.errors;
        }-*/;

        public final native JavaScriptObject getData() /*-{
            return this.response.data;
        }-*/;
    }

    public static final String REQUIRE_CONFIRMATION = "_requireConfirmation";

    public AbstractDS(String id) {
        super();
        setID(id);
        setDataFormat(DSDataFormat.JSON);

        OperationBinding fetch = new OperationBinding();
        fetch.setOperationType(DSOperationType.FETCH);
        fetch.setDataProtocol(DSProtocol.POSTPARAMS);

        OperationBinding add = new OperationBinding();
        add.setOperationType(DSOperationType.ADD);
        add.setDataProtocol(DSProtocol.POSTPARAMS);

        OperationBinding update = new OperationBinding();
        update.setOperationType(DSOperationType.UPDATE);
        update.setDataProtocol(DSProtocol.POSTPARAMS);

        OperationBinding remove = new OperationBinding();
        remove.setOperationType(DSOperationType.REMOVE);
        remove.setDataProtocol(DSProtocol.POSTPARAMS);

        setOperationBindings(fetch, add, update, remove);

        setFetchDataURL(ECApplication.encodeURL());
        setAddDataURL(ECApplication.encodeURL());
        setUpdateDataURL(ECApplication.encodeURL());
        setRemoveDataURL(ECApplication.encodeURL());
        setCriteriaPolicy(CriteriaPolicy.DROPONCHANGE);
        setRecordXPath("response/data");
    }

    public String convertToShortDateFormat(String dateFormat) {
        DateTimeFormat sourceFormatter = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss");

        return ECApplication.getDateFormatter().format(sourceFormatter.parse(dateFormat));
    }

    public static String combineXPath(String... parameters) {
        StringBuilder xPath = null;
        if (parameters != null && parameters.length > 0) {
            xPath = new StringBuilder(parameters[0]);
            for (int i = 1; i < parameters.length; i++) {
                xPath.append("/");
                xPath.append(parameters[i]);
            }
        }

        return xPath.toString();
    }

    @Override
    protected Object transformRequest(DSRequest dsRequest) {
        return super.transformRequest(cleanRequest(dsRequest));
    }

    /**
     * 
     * @param dsRequest
     * @return
     */
    protected DSRequest cleanRequest(DSRequest dsRequest) {
        JavaScriptObject jso = dsRequest.getData();
        String[] properties = JSOHelper.getProperties(jso);
        for (String prop : properties) {
            if (JSOHelper.getAttribute(jso, prop) == null) {
                JSOHelper.deleteAttribute(jso, prop);
            } else {
                // System.out.println(JSOHelper.getAttribute(jso, prop));
                // JSOHelper.setAttribute(jso, prop, JSOHelper.getAttribute(jso,
                // prop).trim());
            }
        }

        if (dsRequest.getAttributeAsBoolean(REQUIRE_CONFIRMATION)) {
            JSOHelper.setAttribute(jso, REQUIRE_CONFIRMATION, dsRequest.getAttribute(REQUIRE_CONFIRMATION));
        }
        dsRequest.setData(jso);

        return dsRequest;
    }

    @Override
    protected void transformResponse(DSResponse response, DSRequest request, Object data) {
        GWT.log("Transform Response");
        GWT.log(JSON.encode((JavaScriptObject) data));
        Response res = (Response) data;
        response.setStatus(res.getStatus());
        response.setErrors(res.getErrors());
        response.setAttribute(REQUIRE_CONFIRMATION, res.getRequireConfirmation());
        GWT.log("Stop Transform Response");
        super.transformResponse(response, request, data);
    }
}
